import os
import uuid
from flask import Flask, request, send_file, jsonify
from werkzeug.utils import secure_filename
from pathlib import Path
from input_parser import parse_input_text
from ppt_generator import generate_presentation
from template_manager import load_template, get_layout_mapping
from layout_manager import LayoutManager
from config import Config
from logger import LOG
from content_formatter import ContentFormatter
from content_assistant import ContentAssistant
from docx_parser import generate_markdown_from_docx

app = Flask(__name__)
# 获取当前文件的绝对路径并确定项目根目录
basedir = Path(__file__).parent.absolute()
app.config['UPLOAD_FOLDER'] = str(basedir / 'uploads')
app.config['OUTPUT_FOLDER'] = str(basedir / 'outputs')
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB限制
app.config['ALLOWED_EXTENSIONS'] = {'md', 'markdown', 'docx'}

# 确保上传和输出目录存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['OUTPUT_FOLDER'], exist_ok=True)


def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']


def process_input(input_path, output_path):
    try:
        # 确保输出目录存在
        Path(output_path).parent.mkdir(parents=True, exist_ok=True)

        config = Config()
        content_formatter = ContentFormatter()
        content_assistant = ContentAssistant()

        # 检查文件类型
        file_ext = os.path.splitext(input_path)[1].lower()
        if file_ext in ['.md', '.markdown']:
            with open(input_path, 'r', encoding='utf-8') as f:
                input_text = f.read()
        elif file_ext == '.docx':
            raw_content = generate_markdown_from_docx(input_path)
            markdown_content = content_formatter.format(raw_content)
            input_text = content_assistant.adjust_single_picture(markdown_content)
        else:
            return False, "Unsupported file format"

        LOG.error(f"PPTMark内容: {input_text}")
        # 加载模板并解析内容
        ppt_template = load_template(config.ppt_template)
        layout_manager = LayoutManager(get_layout_mapping(ppt_template))
        ppt_data, title = parse_input_text(input_text, layout_manager)

        # 生成PPT
        generate_presentation(ppt_data, config.ppt_template, output_path)
        # 验证文件是否生成成功
        if not Path(output_path).exists():
            raise FileNotFoundError(f"生成文件失败：{output_path}")

        return True, output_path

    except Exception as e:
        LOG.error(f"Processing error: {str(e)}")
        return False, str(e)


@app.route('/generate', methods=['POST'])
def handle_generation():
    if 'file' not in request.files:
        return jsonify({"error": "No file provided"}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({"error": "Empty filename"}), 400

    if not allowed_file(file.filename):
        return jsonify({"error": "Invalid file type"}), 400

    # 保存上传文件
    upload_id = uuid.uuid4().hex
    input_ext = os.path.splitext(file.filename)[1]

    input_filename = f"{upload_id}{input_ext}"
    input_path = os.path.join(app.config['UPLOAD_FOLDER'], input_filename)
    file.save(input_path)

    # 准备输出路径
    output_filename = f"{upload_id}.pptx"
    output_path = os.path.join(app.config['OUTPUT_FOLDER'], output_filename)

    # 处理文件
    success, result = process_input(input_path, output_path)


    # 清理输入文件
    try:
        os.remove(input_path)
    except Exception as e:
        LOG.warning(f"清理输入文件失败：{str(e)}")

    if not success:
        return jsonify({"error": result}), 500

    try:
        # 发送前再次确认文件存在
        if not Path(output_path).exists():
            raise FileNotFoundError(f"输出文件不存在：{output_path}")

        LOG.info(f"准备发送文件：{output_path} (大小：{Path(output_path).stat().st_size}字节)")

        return send_file(
            output_path,
            as_attachment=True,
            download_name="Generated-Presentation.pptx",
            mimetype='application/vnd.openxmlformats-officedocument.presentationml.presentation'
        )
    except Exception as e:
        LOG.error(f"文件发送失败：{str(e)}", exc_info=True)
        return jsonify({"error": "文件生成成功但发送失败"}), 500
    finally:
        # 添加延迟清理（可选）
        try:
            # 可以添加1分钟的延迟清理
            pass
        except:
            pass


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5010, debug=True)